#include "InputManager.h"

InputManager::InputManager() : mouse(0), keyboard(0), inputManager(0)
{
}

void InputManager::initialise(Ogre::RenderWindow *rw)
{
	OIS::ParamList pl;
	size_t windowHnd = 0;
	std::ostringstream windowHndStr;
	rw->getCustomAttribute("WINDOW", &windowHnd);
	windowHndStr << windowHnd;
	pl.insert(std::make_pair(std::string("WINDOW"),windowHndStr.str()));
	inputManager = OIS::InputManager::createInputSystem(pl);
	keyboard = static_cast<OIS::Keyboard*>(inputManager->createInputObject(OIS::OISKeyboard,true));
	mouse = static_cast<OIS::Mouse*>(inputManager->createInputObject(OIS::OISMouse,true));
	keyboard->setEventCallback(this);
	mouse->setEventCallback(this);
	setWindowSize(rw->getWidth(), rw->getHeight());
}

void InputManager::capture()
{
	if (mouse) mouse->capture();
	if (keyboard) keyboard->capture();
}

void InputManager::setWindowSize(int w, int h)
{
	if (mouse)
	{
		const OIS::MouseState &ms = mouse->getMouseState();
		ms.width = w;
		ms.height = h;
	}
	width = w;
	height = h;
}

bool InputManager::addKeyListener(OIS::KeyListener *kl, std::string name)
{
	if (keyListeners[name]==NULL)
	{
		keyListeners[name]=kl;
		return true;
	}
	else return false;
}

bool InputManager::addMouseListener(OIS::MouseListener *ml, std::string name)
{
	if (mouseListeners[name]==NULL)
	{
		mouseListeners[name]=ml;
		return true;
	}
	else return false;
}

bool InputManager::removeKeyListener(std::string name)
{
	return keyListeners.erase(name)!=0;
}

bool InputManager::removeMouseListener(std::string name)
{
	return mouseListeners.erase(name)!=0;
}

void InputManager::removeAllKeyListeners()
{
	keyListeners.clear();
}

void InputManager::removeAllMouseListeners()
{
	mouseListeners.clear();
}

bool InputManager::releaseMouse()
{
	if (mouse)
	{
		inputManager->destroyInputObject(mouse);
		mouse = 0;
		return true;
	}
	else return false;
}

bool InputManager::grabMouse()
{
	if (!mouse)
	{
		mouse = static_cast<OIS::Mouse*>(inputManager->createInputObject(OIS::OISMouse, true));
		mouse->setEventCallback(this);
		setWindowSize(width,height);
		return true;
	}
	else return false;
}

bool InputManager::keyPressed(const OIS::KeyEvent &evt)
{
	for (std::map<std::string, OIS::KeyListener*>::iterator it = keyListeners.begin(); it != keyListeners.end(); it++)
		if (!it->second->keyPressed(evt)) return false;
	return true;
}

bool InputManager::keyReleased(const OIS::KeyEvent &evt)
{
	for (std::map<std::string, OIS::KeyListener*>::iterator it = keyListeners.begin(); it != keyListeners.end(); it++)
		if (!it->second->keyReleased(evt)) return false;
	return true;
}
bool InputManager::mouseMoved(const OIS::MouseEvent &evt)
{
	for (std::map<std::string, OIS::MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); it++)
		if (!it->second->mouseMoved(evt)) return false;
	return true;
}
bool InputManager::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
	for (std::map<std::string, OIS::MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); it++)
		if (!it->second->mousePressed(evt,id)) return false;
	return true;
}
bool InputManager::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID id)
{
	for (std::map<std::string, OIS::MouseListener*>::iterator it = mouseListeners.begin(); it != mouseListeners.end(); it++)
		if (!it->second->mouseReleased(evt,id)) return false;
	return true;
}